/*
 * Copyright 2016, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.androidthings.myproject;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

import com.example.androidthings.myproject.applist.AppListActivity;
import com.example.androidthings.myproject.server.ThingsServer;
import com.google.android.things.pio.Gpio;
import com.google.android.things.pio.PeripheralManagerService;
import com.yanzhenjie.andserver.AndServer;
import com.yanzhenjie.andserver.Server;

import org.apache.http.entity.StringEntity;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.IOException;
import java.util.List;

import static android.R.attr.value;

/**
 * 白--gpio16  11  BCM16  in1
 * 红--gpio26  12  BCM26  in2
 * 蓝--gpio20  13  BCM20  in3
 * 青--gpio21  15  BCM21  in4
 * <p>
 * <p>
 * <p>
 * Skeleton of the main Android Things activity. Implement your device's logic
 * in this class.
 * <p>
 * Android Things peripheral APIs are accessible through the class
 * PeripheralManagerService. For example, the snippet below will open a GPIO pin and
 * set it to HIGH:
 * <p>
 * <pre>{@code
 * PeripheralManagerService service = new PeripheralManagerService();
 * mLedGpio = service.openGpio("BCM6");
 * mLedGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
 * mLedGpio.setValue(true);
 * }</pre>
 * <p>
 * For more complex peripherals, look for an existing user-space driver, or implement one if none
 * is available.
 */
public class MainActivity extends Activity implements View.OnTouchListener {
    private static final String TAG = MainActivity.class.getSimpleName();
    PeripheralManagerService manager = new PeripheralManagerService();
    List<String> portList = manager.getGpioList();

    private final static String i1 = "BCM16";
    private final static String i2 = "BCM26";
    private final static String i3 = "BCM20";
    private final static String i4 = "BCM21";
    private Gpio II1;
    private Gpio II2;
    private Gpio II3;
    private Gpio II4;
    private boolean longClicked = false;
    private boolean[] cmd_back = {true, false, true, false};
    private boolean[] cmd_forward = {false, true, false, true};
    private boolean[] cmd_right = {false, true, false, false};
    private boolean[] cmd_left = {false, false, false, true};
    private ThingsServer thingsServer;

    private Server server;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Log.d(TAG, "onCreate");
        thingsServer = new ThingsServer(this);
        server = thingsServer.getServer().createServer();
        server.start();

        setContentView(R.layout.activity_main);
        initEvent();

    }

    private void initEvent() {
        findViewById(R.id.top).setOnTouchListener(this);
        findViewById(R.id.left).setOnTouchListener(this);
        findViewById(R.id.right).setOnTouchListener(this);
        findViewById(R.id.bottom).setOnTouchListener(this);
    }

    @Override
    protected void onResume() {

        super.onResume();
        if (portList.isEmpty()) {

            Log.e(TAG, "No GPIO port available on this device.");

        } else {

            Log.e(TAG, "List of available ports: " +
                    portList);

        }
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                Log.e(TAG, "run: " + server.isRunning());
                if (!server.isRunning()) {
                    server.start();
                }
            }
        }, 5000);
    }


    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.button1:
                init();
                break;
            case R.id.button2://left_back
                try {
                    II1.setValue(true);
                    II2.setValue(false);
                    II3.setValue(false);
                    II4.setValue(false);

                    Toast.makeText(this, "button2 success", Toast.LENGTH_SHORT).show();
                } catch (IOException e) {
                    Log.e(TAG, "button2:  fail");
                    e.printStackTrace();
                }
                break;
            case R.id.button3://left_forward
                try {
                    II1.setValue(false);
                    II2.setValue(true);
                    II3.setValue(false);
                    II4.setValue(false);

                    Toast.makeText(this, "button2 success", Toast.LENGTH_SHORT).show();
                } catch (IOException e) {
                    Log.e(TAG, "button2:  fail");
                    e.printStackTrace();
                }

                break;
            case R.id.button4:

                try {
                    II1.setValue(false);
                    II2.setValue(false);
                    II3.setValue(true);
                    II4.setValue(false);
                } catch (IOException e) {
                    Log.e(TAG, "button2:  fail");
                    e.printStackTrace();
                }

                break;
            case R.id.button5:
                try {
                    II1.setValue(false);
                    II2.setValue(false);
                    II3.setValue(false);
                    II4.setValue(true);

                    Toast.makeText(this, "button2 success", Toast.LENGTH_SHORT).show();
                } catch (IOException e) {
                    Log.e(TAG, "button2:  fail");
                    e.printStackTrace();
                }

                break;
            case R.id.button6:
                try {
                    II1.setValue(false);
                    II2.setValue(false);
                    II3.setValue(false);
                    II4.setValue(false);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                break;
            case R.id.button7:
                startActivity(new Intent(this, AppListActivity.class));
                break;

        }
    }

    private void init() {
        if (II1 != null) {
            try {
                II1.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (II2 != null) {
            try {
                II2.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (II3 != null) {
            try {
                II3.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (II4 != null) {
            try {
                II4.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try {
            II1 = manager.openGpio(i1);
            II2 = manager.openGpio(i2);
            II3 = manager.openGpio(i3);
            II4 = manager.openGpio(i4);
            II1.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
            II2.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
            II3.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
            II4.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
            Toast.makeText(this, "init success", Toast.LENGTH_SHORT).show();
        } catch (IOException e) {
            e.printStackTrace();
            Log.e(TAG, "button1 fail: ");
        }
    }

    private void carAction(boolean[] b, int time) {
        try {
            II1.setValue(b[0]);
            II2.setValue(b[1]);
            II3.setValue(b[2]);
            II4.setValue(b[3]);
            SystemClock.sleep(time);
            II1.setValue(false);
            II2.setValue(false);
            II3.setValue(false);
            II4.setValue(false);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy");
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(String event) {
        switch (event) {
            case "forward":
                carAction(cmd_forward, 200);
                break;
            case "back":
                carAction(cmd_back, 200);
                break;
            case "left":
                carAction(cmd_left, 200);
                break;
            case "right":
                carAction(cmd_right, 200);
                break;
            default:

        }
    }

    ;

    @Override
    protected void onStart() {
        super.onStart();
        EventBus.getDefault().register(this);
    }

    @Override
    protected void onStop() {
        super.onStop();
        EventBus.getDefault().unregister(this);
    }

    @Override
    public boolean onTouch(final View v, MotionEvent event) {
        Log.e("yj.chen", "onTouch");
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            Log.e("yj.chen", "ACTION_DOWN");
            longClicked = true;
            Thread t = new Thread() {
                @Override
                public void run() {
                    super.run();
                    while (longClicked) {

                        switch (v.getId()) {
                            case R.id.top:
                                carAction(cmd_forward, 200);
                                break;
                            case R.id.bottom:
                                carAction(cmd_back, 200);
                                break;
                            case R.id.left:
                                carAction(cmd_left, 200);
                                break;
                            case R.id.right:
                                carAction(cmd_right, 200);
                                break;

                        }
                        try {
                            Thread.sleep(1);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        Log.e("yj.chen", "run end");
                    }
                }
            };
            t.start();

        } else if (event.getAction() == MotionEvent.ACTION_UP) {
            longClicked = false;
            Log.d("yj.chen", "ACTION_UP");
        }
        return true;

    }
}